package downloader

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"strings"
	"sync"
	"utility/common"
)

type SavedFile struct {
	Origin string
	Saved  string
}

type Downloader struct {
	TargetUrls []string
	SavingDir  string
	SavedFiles []SavedFile
}

func (c *Downloader) Start() (err error) {
	var wg sync.WaitGroup
	wg.Add(len(c.TargetUrls))
	for _, v := range c.TargetUrls {
		if !strings.HasPrefix(v, "http") {
			err = errors.New("URL:" + v + "并不是一个正常的URL，URL的开始须以HTTP开头")
			return err
		}
		go func(savePath, targetUrl string, w *sync.WaitGroup) {
			err = os.MkdirAll(c.SavingDir, 0777)
			if err != nil {
				fmt.Println(err)
				wg.Done()
				return
			}
			var filename string
			resp, err := http.Get(targetUrl)
			if err != nil {
				wg.Done()
				return
			}
			disposition := resp.Header.Get("Content-Disposition")
			strs := strings.Split(disposition, ";")
			// 查找文件名
			for _, v := range strs {
				kv := strings.Split(v, "=")
				if len(kv) > 1 {
					key := kv[0]
					value := kv[1]
					if strings.Contains(strings.ToLower(key), "filename") {
						filename = value
					}
				}
			}
			if filename == "" {
				// 如果没有找到，则从URL的参数中获取文件名
				strs := strings.Split(targetUrl, "?")
				if len(strs) > 1 {
					params := strs[1]
					tmp := strings.Split(params, "&")
					for _, v := range tmp {
						kv := strings.Split(v, "=")
						if len(kv) > 1 {
							key := kv[0]
							value := kv[1]
							if strings.Contains(strings.ToLower(key), "filename") {
								filename = value
							}
						}
					}
				} else {
					index := strings.LastIndex(targetUrl, "/")
					if index != -1 {
						filename = targetUrl[index+1:]
					}
				}
			}
			if filename == "" {
				filename = common.RandOrderNo()
			}
			// 至此 文件名以随机数结束，如果多个地方获取不到文件名的话。
			// 开始下载
			// 开始组装保存地址
			filePath := MakeSavePath(c.SavingDir, filename)
			// 组装完毕
			data, err := ioutil.ReadAll(resp.Body)
			defer resp.Body.Close()
			if err != nil {
				wg.Done()
				return
			}
			if err := ioutil.WriteFile(filePath, data, 0644); err != nil {
				fmt.Println(err)
				wg.Done()
				return
			} else {
				fmt.Println("下载成功")
				sf := SavedFile{
					Origin: targetUrl,
					Saved:  filePath,
				}
				c.SavedFiles = append(c.SavedFiles, sf)
				wg.Done()
				return
			}

		}(c.SavingDir, v, &wg)
	}
	wg.Wait()
	return
}
func MakeSavePath(savePath, filename string) (filePath string) {
	if common.Exist(path.Join(savePath, filename)) {
		filenameWithoutSuffix, suffix := GetFileNameWithoutSuffixAndSuffix(filename)
		newFileName := filenameWithoutSuffix + "1." + suffix
		return MakeSavePath(savePath, newFileName)
	} else {
		return path.Join(savePath, filename)
	}
}

func GetFileNameWithoutSuffixAndSuffix(filename string) (filenameWithoutSuffix, suffix string) {
	pointIndex := strings.LastIndex(filename, ".")
	if pointIndex != -1 {
		filenameWithoutSuffix = filename[:pointIndex]
		suffix = filename[pointIndex+1:]
	}
	return
}
